/*
å½•éŸ³
https://github.com/xiangyuecn/Recorder
*/
(function(factory){
	factory(window);
	//umd returnExports.js
	if(typeof(define)=='function' && define.amd){
		define(function(){
			return Recorder;
		});
	};
	if(typeof(module)=='object' && module.exports){
		module.exports=Recorder;
	};
}(function(window){
"use strict";

//å…¼å®¹çŽ¯å¢ƒ
var LM="2021-08-03 20:01:03";
var NOOP=function(){};
//end å…¼å®¹çŽ¯å¢ƒ ****ä»Žä»¥ä¸‹å¼€å§‹copyæºç *****

var Recorder=function(set){
	return new initFn(set);
};
//æ˜¯å¦å·²ç»æ‰“å¼€äº†å…¨å±€çš„éº¦å…‹é£Žå½•éŸ³ï¼Œæ‰€æœ‰å·¥ä½œéƒ½å·²ç»å‡†å¤‡å¥½äº†ï¼Œå°±ç­‰æŽ¥æ”¶éŸ³é¢‘æ•°æ®äº†
Recorder.IsOpen=function(){
	var stream=Recorder.Stream;
	if(stream){
		var tracks=stream.getTracks&&stream.getTracks()||stream.audioTracks||[];
		var track=tracks[0];
		if(track){
			var state=track.readyState;
			return state=="live"||state==track.LIVE;
		};
	};
	return false;
};
/*H5å½•éŸ³æ—¶çš„AudioContextç¼“å†²å¤§å°ã€‚ä¼šå½±å“H5å½•éŸ³æ—¶çš„onProcessè°ƒç”¨é€ŸçŽ‡ï¼Œç›¸å¯¹äºŽAudioContext.sampleRate=48000æ—¶ï¼Œ4096æŽ¥è¿‘12å¸§/sï¼Œè°ƒèŠ‚æ­¤å‚æ•°å¯ç”Ÿæˆæ¯”è¾ƒæµç•…çš„å›žè°ƒåŠ¨ç”»ã€‚
	å–å€¼256, 512, 1024, 2048, 4096, 8192, or 16384
	æ³¨æ„ï¼Œå–å€¼ä¸èƒ½è¿‡ä½Žï¼Œ2048å¼€å§‹ä¸åŒæµè§ˆå™¨å¯èƒ½å›žè°ƒé€ŸçŽ‡è·Ÿä¸ä¸Šé€ æˆéŸ³è´¨é—®é¢˜ã€‚
	ä¸€èˆ¬æ— éœ€è°ƒæ•´ï¼Œè°ƒæ•´åŽéœ€è¦å…ˆcloseæŽ‰å·²æ‰“å¼€çš„å½•éŸ³ï¼Œå†openæ—¶æ‰ä¼šç”Ÿæ•ˆã€‚
*/
Recorder.BufferSize=4096;
//é”€æ¯å·²æŒæœ‰çš„æ‰€æœ‰å…¨å±€èµ„æºï¼Œå½“è¦å½»åº•ç§»é™¤Recorderæ—¶éœ€è¦æ˜¾å¼çš„è°ƒç”¨æ­¤æ–¹æ³•
Recorder.Destroy=function(){
	CLog("Recorder Destroy");
	Disconnect();//æ–­å¼€å¯èƒ½å­˜åœ¨çš„å…¨å±€Streamã€èµ„æº
	
	for(var k in DestroyList){
		DestroyList[k]();
	};
};
var DestroyList={};
//ç™»è®°ä¸€ä¸ªéœ€è¦é”€æ¯å…¨å±€èµ„æºçš„å¤„ç†æ–¹æ³•
Recorder.BindDestroy=function(key,call){
	DestroyList[key]=call;
};
//åˆ¤æ–­æµè§ˆå™¨æ˜¯å¦æ”¯æŒå½•éŸ³ï¼Œéšæ—¶å¯ä»¥è°ƒç”¨ã€‚æ³¨æ„ï¼šä»…ä»…æ˜¯æ£€æµ‹æµè§ˆå™¨æ”¯æŒæƒ…å†µï¼Œä¸ä¼šåˆ¤æ–­å’Œè°ƒèµ·ç”¨æˆ·æŽˆæƒï¼Œä¸ä¼šåˆ¤æ–­æ˜¯å¦æ”¯æŒç‰¹å®šæ ¼å¼å½•éŸ³ã€‚
Recorder.Support=function(){
	var AC=window.AudioContext;
	if(!AC){
		AC=window.webkitAudioContext;
	};
	if(!AC){
		return false;
	};
	var scope=navigator.mediaDevices||{};
	if(!scope.getUserMedia){
		scope=navigator;
		scope.getUserMedia||(scope.getUserMedia=scope.webkitGetUserMedia||scope.mozGetUserMedia||scope.msGetUserMedia);
	};
	if(!scope.getUserMedia){
		return false;
	};
	
	Recorder.Scope=scope;
	if(!Recorder.Ctx||Recorder.Ctx.state=="closed"){
		//ä¸èƒ½åå¤æž„é€ ï¼Œä½Žç‰ˆæœ¬number of hardware contexts reached maximum (6)
		Recorder.Ctx=new AC();
		
		Recorder.BindDestroy("Ctx",function(){
			var ctx=Recorder.Ctx;
			if(ctx&&ctx.close){//èƒ½å…³æŽ‰å°±å…³æŽ‰ï¼Œå…³ä¸æŽ‰å°±ä¿ç•™ç€
				ctx.close();
				Recorder.Ctx=0;
			};
		});
	};
	return true;
};
/*åˆå§‹åŒ–H5éŸ³é¢‘é‡‡é›†è¿žæŽ¥ã€‚å¦‚æžœè‡ªè¡Œæä¾›äº†sourceStreamå°†åªè¿›è¡Œä¸€æ¬¡ç®€å•çš„è¿žæŽ¥å¤„ç†ã€‚å¦‚æžœæ˜¯æ™®é€šéº¦å…‹é£Žå½•éŸ³ï¼Œæ­¤æ—¶çš„Streamæ˜¯å…¨å±€çš„ï¼ŒSafariä¸Šæ–­å¼€åŽå°±æ— æ³•å†æ¬¡è¿›è¡Œè¿žæŽ¥ä½¿ç”¨ï¼Œè¡¨çŽ°ä¸ºé™éŸ³ï¼Œå› æ­¤ä½¿ç”¨å…¨éƒ¨ä½¿ç”¨å…¨å±€å¤„ç†é¿å…è°ƒç”¨åˆ°disconnectï¼›å…¨å±€å¤„ç†ä¹Ÿæœ‰åˆ©äºŽå±è”½åº•å±‚ç»†èŠ‚ï¼Œstartæ—¶æ— éœ€å†è°ƒç”¨åº•å±‚æŽ¥å£ï¼Œæå‡å…¼å®¹ã€å¯é æ€§ã€‚*/
var Connect=function(streamStore){
	streamStore=streamStore||Recorder;
	var bufferSize=streamStore.BufferSize||Recorder.BufferSize;
	
	var ctx=Recorder.Ctx,stream=streamStore.Stream;
	var media=stream._m=ctx.createMediaStreamSource(stream);
	var process=stream._p=(ctx.createScriptProcessor||ctx.createJavaScriptNode).call(ctx,bufferSize,1,1);//å•å£°é“ï¼Œçœçš„æ•°æ®å¤„ç†å¤æ‚
	
	media.connect(process);
	process.connect(ctx.destination);
	
	var calls=stream._call;
	process.onaudioprocess=function(e){
		for(var k0 in calls){//has item
			var o=e.inputBuffer.getChannelData(0);//å—æ˜¯å…±äº«çš„ï¼Œå¿…é¡»å¤åˆ¶å‡ºæ¥
			var size=o.length;
			
			var pcm=new Int16Array(size);
			var sum=0;
			for(var j=0;j<size;j++){//floatTo16BitPCM 
				var s=Math.max(-1,Math.min(1,o[j]));
				s=s<0?s*0x8000:s*0x7FFF;
				pcm[j]=s;
				sum+=Math.abs(s);
			};
			
			for(var k in calls){
				calls[k](pcm,sum);
			};
			
			return;
		};
	};
};
var Disconnect=function(streamStore){
	streamStore=streamStore||Recorder;
	var isGlobal=streamStore==Recorder;
	
	var stream=streamStore.Stream;
	if(stream){
		if(stream._m){
			stream._m.disconnect();
			stream._p.disconnect();
			stream._p.onaudioprocess=stream._p=stream._m=null;
		};
		
		if(isGlobal){//å…¨å±€çš„æ—¶å€™ï¼Œè¦æŠŠæµå…³æŽ‰ï¼ˆéº¦å…‹é£Žï¼‰ï¼Œç›´æŽ¥æä¾›çš„æµä¸å¤„ç†
			var tracks=stream.getTracks&&stream.getTracks()||stream.audioTracks||[];
			for(var i=0;i<tracks.length;i++){
				var track=tracks[i];
				track.stop&&track.stop();
			};
			stream.stop&&stream.stop();
		};
	};
	streamStore.Stream=0;
};

/*å¯¹pcmæ•°æ®çš„é‡‡æ ·çŽ‡è¿›è¡Œè½¬æ¢
pcmDatas: [[Int16,...]] pcmç‰‡æ®µåˆ—è¡¨
pcmSampleRate:48000 pcmæ•°æ®çš„é‡‡æ ·çŽ‡
newSampleRate:16000 éœ€è¦è½¬æ¢æˆçš„é‡‡æ ·çŽ‡ï¼ŒnewSampleRate>=pcmSampleRateæ—¶ä¸ä¼šè¿›è¡Œä»»ä½•å¤„ç†ï¼Œå°äºŽæ—¶ä¼šè¿›è¡Œé‡æ–°é‡‡æ ·
prevChunkInfo:{} å¯é€‰ï¼Œä¸Šæ¬¡è°ƒç”¨æ—¶çš„è¿”å›žå€¼ï¼Œç”¨äºŽè¿žç»­è½¬æ¢ï¼Œæœ¬æ¬¡è°ƒç”¨å°†ä»Žä¸Šæ¬¡ç»“æŸä½ç½®å¼€å§‹è¿›è¡Œå¤„ç†ã€‚æˆ–å¯è‡ªè¡Œå®šä¹‰ä¸€ä¸ªChunkInfoä»ŽpcmDatasæŒ‡å®šçš„ä½ç½®å¼€å§‹è¿›è¡Œè½¬æ¢
option:{ å¯é€‰ï¼Œé…ç½®é¡¹
		frameSize:123456 å¸§å¤§å°ï¼Œæ¯å¸§çš„PCM Int16çš„æ•°é‡ï¼Œé‡‡æ ·çŽ‡è½¬æ¢åŽçš„pcmé•¿åº¦ä¸ºframeSizeçš„æ•´æ•°å€ï¼Œç”¨äºŽè¿žç»­è½¬æ¢ã€‚ç›®å‰ä»…åœ¨mp3æ ¼å¼æ—¶æ‰æœ‰ç”¨ï¼ŒframeSizeå–å€¼ä¸º1152ï¼Œè¿™æ ·ç¼–ç å‡ºæ¥çš„mp3æ—¶é•¿å’Œpcmçš„æ—¶é•¿å®Œå…¨ä¸€è‡´ï¼Œå¦åˆ™ä¼šå› ä¸ºmp3æœ€åŽä¸€å¸§å½•éŸ³ä¸å¤Ÿå¡«æ»¡æ—¶æ·»åŠ å¡«å……æ•°æ®å¯¼è‡´mp3çš„æ—¶é•¿å˜é•¿ã€‚
		frameType:"" å¸§ç±»åž‹ï¼Œä¸€èˆ¬ä¸ºrec.set.typeï¼Œæä¾›æ­¤å‚æ•°æ—¶æ— éœ€æä¾›frameSizeï¼Œä¼šè‡ªåŠ¨ä½¿ç”¨æœ€ä½³çš„å€¼ç»™frameSizeèµ‹å€¼ï¼Œç›®å‰ä»…æ”¯æŒmp3=1152(MPEG1 Layer3çš„æ¯å¸§é‡‡é‡‡æ ·æ•°)ï¼Œå…¶ä»–ç±»åž‹=1ã€‚
			ä»¥ä¸Šä¸¤ä¸ªå‚æ•°ç”¨äºŽè¿žç»­è½¬æ¢æ—¶ä½¿ç”¨ï¼Œæœ€å¤šä½¿ç”¨ä¸€ä¸ªï¼Œä¸æä¾›æ—¶ä¸è¿›è¡Œå¸§çš„ç‰¹æ®Šå¤„ç†ï¼Œæä¾›æ—¶å¿…é¡»åŒæ—¶æä¾›prevChunkInfoæ‰æœ‰ä½œç”¨ã€‚æœ€åŽä¸€æ®µæ•°æ®å¤„ç†æ—¶æ— éœ€æä¾›å¸§å¤§å°ä»¥ä¾¿è¾“å‡ºæœ€åŽä¸€ä¸ç‚¹æ®‹ç•™æ•°æ®ã€‚
	}

è¿”å›žChunkInfo:{
	//å¯å®šä¹‰ï¼Œä»ŽæŒ‡å®šä½ç½®å¼€å§‹è½¬æ¢åˆ°ç»“å°¾
	index:0 pcmDataså·²å¤„ç†åˆ°çš„ç´¢å¼•
	offset:0.0 å·²å¤„ç†åˆ°çš„indexå¯¹åº”çš„pcmä¸­çš„åç§»çš„ä¸‹ä¸€ä¸ªä½ç½®
	
	//ä»…ä½œä¸ºè¿”å›žå€¼
	frameNext:null||[Int16,...] ä¸‹ä¸€å¸§çš„éƒ¨åˆ†æ•°æ®ï¼ŒframeSizeè®¾ç½®äº†çš„æ—¶å€™æ‰å¯èƒ½ä¼šæœ‰
	sampleRate:16000 ç»“æžœçš„é‡‡æ ·çŽ‡ï¼Œ<=newSampleRate
	data:[Int16,...] è½¬æ¢åŽçš„PCMç»“æžœï¼›å¦‚æžœæ˜¯è¿žç»­è½¬æ¢ï¼Œå¹¶ä¸”pcmDatasä¸­å¹¶æ²¡æœ‰æ–°æ•°æ®æ—¶ï¼Œdataçš„é•¿åº¦å¯èƒ½ä¸º0
}
*/
Recorder.SampleData=function(pcmDatas,pcmSampleRate,newSampleRate,prevChunkInfo,option){
	prevChunkInfo||(prevChunkInfo={});
	var index=prevChunkInfo.index||0;
	var offset=prevChunkInfo.offset||0;
	
	var frameNext=prevChunkInfo.frameNext||[];
	option||(option={});
	var frameSize=option.frameSize||1;
	if(option.frameType){
		frameSize=option.frameType=="mp3"?1152:1;
	};
	
	var size=0;
	for(var i=index;i<pcmDatas.length;i++){
		size+=pcmDatas[i].length;
	};
	size=Math.max(0,size-Math.floor(offset));
	
	//é‡‡æ · https://www.cnblogs.com/blqw/p/3782420.html
	var step=pcmSampleRate/newSampleRate;
	if(step>1){//æ–°é‡‡æ ·ä½ŽäºŽå½•éŸ³é‡‡æ ·ï¼Œè¿›è¡ŒæŠ½æ ·
		size=Math.floor(size/step);
	}else{//æ–°é‡‡æ ·é«˜äºŽå½•éŸ³é‡‡æ ·ä¸å¤„ç†ï¼ŒçœåŽ»äº†æ’å€¼å¤„ç†
		step=1;
		newSampleRate=pcmSampleRate;
	};
	
	size+=frameNext.length;
	var res=new Int16Array(size);
	var idx=0;
	//æ·»åŠ ä¸Šä¸€æ¬¡ä¸å¤Ÿä¸€å¸§çš„å‰©ä½™æ•°æ®
	for(var i=0;i<frameNext.length;i++){
		res[idx]=frameNext[i];
		idx++;
	};
	//å¤„ç†æ•°æ®
	for (var nl=pcmDatas.length;index<nl;index++) {
		var o=pcmDatas[index];
		var i=offset,il=o.length;
		while(i<il){
			//res[idx]=o[Math.round(i)]; ç›´æŽ¥ç®€å•æŠ½æ ·
			
			//https://www.cnblogs.com/xiaoqi/p/6993912.html
			//å½“å‰ç‚¹=å½“å‰ç‚¹+åˆ°åŽé¢ä¸€ä¸ªç‚¹ä¹‹é—´çš„å¢žé‡ï¼ŒéŸ³è´¨æ¯”ç›´æŽ¥ç®€å•æŠ½æ ·å¥½äº›
			var before = Math.floor(i);
			var after = Math.ceil(i);
			var atPoint = i - before;
			
			var beforeVal=o[before];
			var afterVal=after<il ? o[after]
				: (//åŽä¸ªç‚¹è¶Šç•Œäº†ï¼ŒæŸ¥æ‰¾ä¸‹ä¸€ä¸ªæ•°ç»„
					(pcmDatas[index+1]||[beforeVal])[0]||0
				);
			res[idx]=beforeVal+(afterVal-beforeVal)*atPoint;
			
			idx++;
			i+=step;//æŠ½æ ·
		};
		offset=i-il;
	};
	//å¸§å¤„ç†
	frameNext=null;
	var frameNextSize=res.length%frameSize;
	if(frameNextSize>0){
		var u8Pos=(res.length-frameNextSize)*2;
		frameNext=new Int16Array(res.buffer.slice(u8Pos));
		res=new Int16Array(res.buffer.slice(0,u8Pos));
	};
	
	return {
		index:index
		,offset:offset
		
		,frameNext:frameNext
		,sampleRate:newSampleRate
		,data:res
	};
};


/*è®¡ç®—éŸ³é‡ç™¾åˆ†æ¯”çš„ä¸€ä¸ªæ–¹æ³•
pcmAbsSum: pcm Int16æ‰€æœ‰é‡‡æ ·çš„ç»å¯¹å€¼çš„å’Œ
pcmLength: pcmé•¿åº¦
è¿”å›žå€¼ï¼š0-100ï¼Œä¸»è¦å½“åšç™¾åˆ†æ¯”ç”¨
æ³¨æ„ï¼šè¿™ä¸ªä¸æ˜¯åˆ†è´ï¼Œå› æ­¤æ²¡ç”¨volumeå½“åšåç§°*/
Recorder.PowerLevel=function(pcmAbsSum,pcmLength){
	/*è®¡ç®—éŸ³é‡ https://blog.csdn.net/jody1989/article/details/73480259
	æ›´é«˜çµæ•åº¦ç®—æ³•:
		é™å®šæœ€å¤§æ„Ÿåº”å€¼10000
			çº¿æ€§æ›²çº¿ï¼šä½ŽéŸ³é‡ä¸å‹å¥½
				power/10000*100 
			å¯¹æ•°æ›²çº¿ï¼šä½ŽéŸ³é‡å‹å¥½ï¼Œä½†éœ€é™å®šæœ€ä½Žæ„Ÿåº”å€¼
				(1+Math.log10(power/10000))*100
	*/
	var power=(pcmAbsSum/pcmLength) || 0;//NaN
	var level;
	if(power<1251){//1250çš„ç»“æžœ10%ï¼Œæ›´å°çš„éŸ³é‡é‡‡ç”¨çº¿æ€§å–å€¼
		level=Math.round(power/1250*10);
	}else{
		level=Math.round(Math.min(100,Math.max(0,(1+Math.log(power/10000)/Math.log(10))*100)));
	};
	return level;
};




//å¸¦æ—¶é—´çš„æ—¥å¿—è¾“å‡ºï¼ŒCLog(msg,errOrLogMsg, logMsg...) errä¸ºæ•°å­—æ—¶ä»£è¡¨æ—¥å¿—ç±»åž‹1:error 2:logé»˜è®¤ 3:warnï¼Œå¦åˆ™å½“åšå†…å®¹è¾“å‡ºï¼Œç¬¬ä¸€ä¸ªå‚æ•°ä¸èƒ½æ˜¯å¯¹è±¡å› ä¸ºè¦æ‹¼æŽ¥æ—¶é—´ï¼ŒåŽé¢å¯ä»¥æŽ¥æ— æ•°ä¸ªè¾“å‡ºå‚æ•°
var CLog=function(msg,err){
	var now=new Date();
	var t=("0"+now.getMinutes()).substr(-2)
		+":"+("0"+now.getSeconds()).substr(-2)
		+"."+("00"+now.getMilliseconds()).substr(-3);
	var arr=["["+t+" Recorder]"+msg];
	var a=arguments;
	var i=2,fn=console.log;
	if(typeof(err)=="number"){
		fn=err==1?console.error:err==3?console.warn:fn;
	}else{
		i=1;
	};
	for(;i<a.length;i++){
		arr.push(a[i]);
	};
	fn.apply(console,arr);
};
Recorder.CLog=CLog;




var ID=0;
function initFn(set){
	this.id=++ID;
	
	//å¦‚æžœå¼€å¯äº†æµé‡ç»Ÿè®¡ï¼Œè¿™é‡Œå°†å‘é€ä¸€ä¸ªå›¾ç‰‡è¯·æ±‚
	Recorder.Traffic&&Recorder.Traffic();
	
	
	var o={
		type:"mp3" //è¾“å‡ºç±»åž‹ï¼šmp3,wavï¼Œwavè¾“å‡ºæ–‡ä»¶å°ºå¯¸è¶…å¤§ä¸æŽ¨èä½¿ç”¨ï¼Œä½†mp3ç¼–ç æ”¯æŒä¼šå¯¼è‡´jsæ–‡ä»¶è¶…å¤§ï¼Œå¦‚æžœä¸éœ€æ”¯æŒmp3å¯ä»¥ä½¿jsæ–‡ä»¶å¤§å¹…å‡å°
		,bitRate:16 //æ¯”ç‰¹çŽ‡ wav:16æˆ–8ä½ï¼ŒMP3ï¼š8kbps 1k/sï¼Œ8kbps 2k/s å½•éŸ³æ–‡ä»¶å¾ˆå°
		
		,sampleRate:16000 //é‡‡æ ·çŽ‡ï¼Œwavæ ¼å¼å¤§å°=sampleRate*æ—¶é—´ï¼›mp3æ­¤é¡¹å¯¹ä½Žæ¯”ç‰¹çŽ‡æœ‰å½±å“ï¼Œé«˜æ¯”ç‰¹çŽ‡å‡ ä¹Žæ— å½±å“ã€‚
					//wavä»»æ„å€¼ï¼Œmp3å–å€¼èŒƒå›´ï¼š48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000
					//é‡‡æ ·çŽ‡å‚è€ƒhttps://www.cnblogs.com/devin87/p/mp3-recorder.html
		
		,onProcess:NOOP //fn(buffers,powerLevel,bufferDuration,bufferSampleRate,newBufferIdx,asyncEnd) buffers=[[Int16,...],...]ï¼šç¼“å†²çš„PCMæ•°æ®ï¼Œä¸ºä»Žå¼€å§‹å½•éŸ³åˆ°çŽ°åœ¨çš„æ‰€æœ‰pcmç‰‡æ®µï¼›powerLevelï¼šå½“å‰ç¼“å†²çš„éŸ³é‡çº§åˆ«0-100ï¼ŒbufferDurationï¼šå·²ç¼“å†²æ—¶é•¿ï¼ŒbufferSampleRateï¼šç¼“å†²ä½¿ç”¨çš„é‡‡æ ·çŽ‡ï¼ˆå½“typeæ”¯æŒè¾¹å½•è¾¹è½¬ç (Worker)æ—¶ï¼Œæ­¤é‡‡æ ·çŽ‡å’Œè®¾ç½®çš„é‡‡æ ·çŽ‡ç›¸åŒï¼Œå¦åˆ™ä¸ä¸€å®šç›¸åŒï¼‰ï¼›newBufferIdx:æœ¬æ¬¡å›žè°ƒæ–°å¢žçš„bufferèµ·å§‹ç´¢å¼•ï¼›asyncEnd:fn() å¦‚æžœonProcessæ˜¯å¼‚æ­¥çš„(è¿”å›žå€¼ä¸ºtrueæ—¶)ï¼Œå¤„ç†å®Œæˆæ—¶éœ€è¦è°ƒç”¨æ­¤å›žè°ƒï¼Œå¦‚æžœä¸æ˜¯å¼‚æ­¥çš„è¯·å¿½ç•¥æ­¤å‚æ•°ï¼Œæ­¤æ–¹æ³•å›žè°ƒæ—¶å¿…é¡»æ˜¯çœŸå¼‚æ­¥ï¼ˆä¸èƒ½çœŸå¼‚æ­¥æ—¶éœ€ç”¨setTimeoutåŒ…è£¹ï¼‰ã€‚onProcessè¿”å›žå€¼ï¼šå¦‚æžœè¿”å›žtrueä»£è¡¨å¼€å¯å¼‚æ­¥æ¨¡å¼ï¼Œåœ¨æŸäº›å¤§é‡è¿ç®—çš„åœºåˆå¼‚æ­¥æ˜¯å¿…é¡»çš„ï¼Œå¿…é¡»åœ¨å¼‚æ­¥å¤„ç†å®Œæˆæ—¶è°ƒç”¨asyncEnd(ä¸èƒ½çœŸå¼‚æ­¥æ—¶éœ€ç”¨setTimeoutåŒ…è£¹)ï¼Œåœ¨onProcessæ‰§è¡ŒåŽæ–°å¢žçš„bufferä¼šå…¨éƒ¨æ›¿æ¢æˆç©ºæ•°ç»„ï¼Œå› æ­¤æœ¬å›žè°ƒå¼€å¤´åº”ç«‹å³å°†newBufferIdxåˆ°æœ¬æ¬¡å›žè°ƒç»“å°¾ä½ç½®çš„bufferå…¨éƒ¨ä¿å­˜åˆ°å¦å¤–ä¸€ä¸ªæ•°ç»„å†…ï¼Œå¤„ç†å®ŒæˆåŽå†™å›žbuffersä¸­æœ¬æ¬¡å›žè°ƒçš„ç»“å°¾ä½ç½®ã€‚
		
		//*******é«˜çº§è®¾ç½®******
		//,sourceStream:MediaStream Object
				//å¯é€‰ç›´æŽ¥æä¾›ä¸€ä¸ªåª’ä½“æµï¼Œä»Žè¿™ä¸ªæµä¸­å½•åˆ¶ã€å®žæ—¶å¤„ç†éŸ³é¢‘æ•°æ®ï¼ˆå½“å‰Recorderå®žä¾‹ç‹¬äº«æ­¤æµï¼‰ï¼›ä¸æä¾›æ—¶ä¸ºæ™®é€šçš„éº¦å…‹é£Žå½•éŸ³ï¼Œç”±getUserMediaæä¾›éŸ³é¢‘æµï¼ˆæ‰€æœ‰Recorderå®žä¾‹å…±äº«åŒä¸€ä¸ªæµï¼‰
				//æ¯”å¦‚ï¼šaudioã€videoæ ‡ç­¾domèŠ‚ç‚¹çš„captureStreamæ–¹æ³•ï¼ˆå®žéªŒç‰¹æ€§ï¼Œä¸åŒæµè§ˆå™¨æ”¯æŒç¨‹åº¦ä¸é«˜ï¼‰è¿”å›žçš„æµï¼›WebRTCä¸­çš„remoteæµï¼›è‡ªå·±åˆ›å»ºçš„æµç­‰
				//æ³¨æ„ï¼šæµå†…å¿…é¡»è‡³å°‘å­˜åœ¨ä¸€æ¡éŸ³è½¨(Audio Track)ï¼Œæ¯”å¦‚audioæ ‡ç­¾å¿…é¡»ç­‰å¾…åˆ°å¯ä»¥å¼€å§‹æ’­æ”¾åŽæ‰ä¼šæœ‰éŸ³è½¨ï¼Œå¦åˆ™openä¼šå¤±è´¥
		
		//,audioTrackSet:{ deviceId:"",groupId:"", autoGainControl:true, echoCancellation:true, noiseSuppression:true }
				//æ™®é€šéº¦å…‹é£Žå½•éŸ³æ—¶getUserMediaæ–¹æ³•çš„audioé…ç½®å‚æ•°ï¼Œæ¯”å¦‚æŒ‡å®šè®¾å¤‡idï¼Œå›žå£°æ¶ˆé™¤ã€é™å™ªå¼€å…³ï¼›æ³¨æ„ï¼šæä¾›çš„ä»»ä½•é…ç½®å€¼éƒ½ä¸ä¸€å®šä¼šç”Ÿæ•ˆ
				//ç”±äºŽéº¦å…‹é£Žæ˜¯å…¨å±€å…±äº«çš„ï¼Œæ‰€ä»¥æ–°é…ç½®åŽéœ€è¦closeæŽ‰ä»¥å‰çš„å†é‡æ–°open
				//æ›´å¤šå‚è€ƒ: https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints
		
		//,disableEnvInFix:false å†…éƒ¨å‚æ•°ï¼Œç¦ç”¨è®¾å¤‡å¡é¡¿æ—¶éŸ³é¢‘è¾“å…¥ä¸¢å¤±è¡¥å¿åŠŸèƒ½
		
		//,takeoffEncodeChunk:NOOP //fn(chunkBytes) chunkBytes=[Uint8,...]ï¼šå®žæ—¶ç¼–ç çŽ¯å¢ƒä¸‹æŽ¥ç®¡ç¼–ç å™¨è¾“å‡ºï¼Œå½“ç¼–ç å™¨å®žæ—¶ç¼–ç å‡ºä¸€å—æœ‰æ•ˆçš„äºŒè¿›åˆ¶éŸ³é¢‘æ•°æ®æ—¶å®žæ—¶å›žè°ƒæ­¤æ–¹æ³•ï¼›å‚æ•°ä¸ºäºŒè¿›åˆ¶çš„Uint8Arrayï¼Œå°±æ˜¯ç¼–ç å‡ºæ¥çš„éŸ³é¢‘æ•°æ®ç‰‡æ®µï¼Œæ‰€æœ‰çš„chunkBytesæ‹¼æŽ¥åœ¨ä¸€èµ·å³ä¸ºå®Œæ•´éŸ³é¢‘ã€‚æœ¬å®žçŽ°çš„æƒ³æ³•æœ€åˆç”±QQ2543775048æå‡º
				//å½“æä¾›æ­¤å›žè°ƒæ–¹æ³•æ—¶ï¼Œå°†æŽ¥ç®¡ç¼–ç å™¨çš„æ•°æ®è¾“å‡ºï¼Œç¼–ç å™¨å†…éƒ¨å°†æ”¾å¼ƒå­˜å‚¨ç”Ÿæˆçš„éŸ³é¢‘æ•°æ®ï¼›çŽ¯å¢ƒè¦æ±‚æ¯”è¾ƒè‹›åˆ»ï¼šå¦‚æžœå½“å‰çŽ¯å¢ƒä¸æ”¯æŒå®žæ—¶ç¼–ç å¤„ç†ï¼Œå°†åœ¨openæ—¶ç›´æŽ¥èµ°failé€»è¾‘
				//å› æ­¤æä¾›æ­¤å›žè°ƒåŽè°ƒç”¨stopæ–¹æ³•å°†æ— æ³•èŽ·å¾—æœ‰æ•ˆçš„éŸ³é¢‘æ•°æ®ï¼Œå› ä¸ºç¼–ç å™¨å†…æ²¡æœ‰éŸ³é¢‘æ•°æ®ï¼Œå› æ­¤stopæ—¶è¿”å›žçš„blobå°†æ˜¯ä¸€ä¸ªå­—èŠ‚é•¿åº¦ä¸º0çš„blob
				//ç›®å‰åªæœ‰mp3æ ¼å¼å®žçŽ°äº†å®žæ—¶ç¼–ç ï¼Œåœ¨æ”¯æŒå®žæ—¶å¤„ç†çš„çŽ¯å¢ƒä¸­å°†ä¼šå®žæ—¶çš„å°†ç¼–ç å‡ºæ¥çš„mp3ç‰‡æ®µé€šè¿‡æ­¤æ–¹æ³•å›žè°ƒï¼Œæ‰€æœ‰çš„chunkBytesæ‹¼æŽ¥åˆ°ä¸€èµ·å³ä¸ºå®Œæ•´çš„mp3ï¼Œæ­¤ç§æ‹¼æŽ¥çš„ç»“æžœæ¯”mockæ–¹æ³•å®žæ—¶ç”Ÿæˆçš„éŸ³è´¨æ›´åŠ ï¼Œå› ä¸ºå¤©ç„¶é¿å…äº†é¦–å°¾çš„é™é»˜
				//ç›®å‰é™¤mp3å¤–å…¶ä»–æ ¼å¼ä¸å¯ä»¥æä¾›æ­¤å›žè°ƒï¼Œæä¾›äº†å°†åœ¨openæ—¶ç›´æŽ¥èµ°failé€»è¾‘
	};
	
	for(var k in set){
		o[k]=set[k];
	};
	this.set=o;
	
	this._S=9;//stopåŒæ­¥é”ï¼Œstopå¯ä»¥é˜»æ­¢openè¿‡ç¨‹ä¸­è¿˜æœªè¿è¡Œçš„start
	this.Sync={O:9,C:9};//å’ŒRecorder.Syncä¸€è‡´ï¼Œåªä¸è¿‡è¿™ä¸ªæ˜¯éžå…¨å±€çš„ï¼Œä»…ç”¨æ¥ç®€åŒ–ä»£ç é€»è¾‘ï¼Œæ— å®žé™…ä½œç”¨
};
//åŒæ­¥é”ï¼ŒæŽ§åˆ¶å¯¹Streamçš„ç«žäº‰ï¼›ç”¨äºŽcloseæ—¶ä¸­æ–­å¼‚æ­¥çš„openï¼›ä¸€ä¸ªå¯¹è±¡openå¦‚æžœå˜åŒ–äº†éƒ½è¦é˜»æ­¢closeï¼ŒStreamçš„æŽ§åˆ¶æƒäº¤ä¸ªæ–°çš„å¯¹è±¡
Recorder.Sync={/*open*/O:9,/*close*/C:9};

Recorder.prototype=initFn.prototype={
	//æµç›¸å…³çš„æ•°æ®å­˜å‚¨åœ¨å“ªä¸ªå¯¹è±¡é‡Œé¢ï¼›å¦‚æžœæä¾›äº†sourceStreamï¼Œæ•°æ®ç›´æŽ¥å­˜å‚¨åœ¨å½“å‰å¯¹è±¡ä¸­ï¼Œå¦åˆ™å­˜å‚¨åœ¨å…¨å±€
	_streamStore:function(){
		if(this.set.sourceStream){
			return this;
		}else{
			return Recorder;
		}
	}
	
	//æ‰“å¼€å½•éŸ³èµ„æºTrue(),False(msg,isUserNotAllow)ï¼Œéœ€è¦è°ƒç”¨closeã€‚æ³¨æ„ï¼šæ­¤æ–¹æ³•æ˜¯å¼‚æ­¥çš„ï¼›ä¸€èˆ¬ä½¿ç”¨æ—¶æ‰“å¼€ï¼Œç”¨å®Œç«‹å³å…³é—­ï¼›å¯é‡å¤è°ƒç”¨ï¼Œå¯ç”¨æ¥æµ‹è¯•æ˜¯å¦èƒ½å½•éŸ³
	,open:function(True,False){
		var This=this,streamStore=This._streamStore();
		True=True||NOOP;
		var failCall=function(errMsg,isUserNotAllow){
			isUserNotAllow=!!isUserNotAllow;
			CLog("å½•éŸ³openå¤±è´¥ï¼š"+errMsg+",isUserNotAllow:"+isUserNotAllow,1);
			False&&False(errMsg,isUserNotAllow);
		};
		
		var ok=function(){
			CLog("openæˆåŠŸ");
			True();
			
			This._SO=0;//è§£é™¤stopå¯¹openä¸­çš„startè°ƒç”¨çš„é˜»æ­¢
		};
		
		
		//åŒæ­¥é”
		var Lock=streamStore.Sync;
		var lockOpen=++Lock.O,lockClose=Lock.C;
		This._O=This._O_=lockOpen;//è®°ä½å½“å‰çš„openï¼Œå¦‚æžœå˜åŒ–äº†è¦é˜»æ­¢closeï¼Œè¿™é‡Œå‡å®šäº†æ–°å¯¹è±¡å·²å–ä»£å½“å‰å¯¹è±¡å¹¶ä¸”ä¸å†ä½¿ç”¨
		This._SO=This._S;//è®°ä½openè¿‡ç¨‹ä¸­çš„stopï¼Œä¸­é€”ä»»ä½•stopè°ƒç”¨åŽéƒ½ä¸èƒ½ç»§ç»­openä¸­çš„start
		var lockFail=function(){
			//å…è®¸å¤šæ¬¡openï¼Œä½†ä¸å…è®¸ä»»ä½•ä¸€æ¬¡closeï¼Œæˆ–è€…è‡ªèº«å·²ç»è°ƒç”¨äº†å…³é—­
			if(lockClose!=Lock.C || !This._O){
				var err="openè¢«å–æ¶ˆ";
				if(lockOpen==Lock.O){
					//æ— æ–°çš„openï¼Œå·²ç»è°ƒç”¨äº†closeè¿›è¡Œå–æ¶ˆï¼Œæ­¤å¤„åº”è®©ä¸Šæ¬¡çš„closeæ˜Žç¡®ç”Ÿæ•ˆ
					This.close();
				}else{
					err="openè¢«ä¸­æ–­";
				};
				failCall(err);
				return true;
			};
		};
		
		//çŽ¯å¢ƒé…ç½®æ£€æŸ¥
		var checkMsg=This.envCheck({envName:"H5",canProcess:true});
		if(checkMsg){
			failCall("ä¸èƒ½å½•éŸ³ï¼š"+checkMsg);
			return;
		};
		
		
		//***********å·²ç›´æŽ¥æä¾›äº†éŸ³é¢‘æµ************
		if(This.set.sourceStream){
			if(!Recorder.Support()){
				failCall("ä¸æ”¯æŒæ­¤æµè§ˆå™¨ä»Žæµä¸­èŽ·å–å½•éŸ³");
				return;
			};
			
			Disconnect(streamStore);//å¯èƒ½å·²openè¿‡ï¼Œç›´æŽ¥å…ˆå°è¯•æ–­å¼€
			This.Stream=This.set.sourceStream;
			This.Stream._call={};
			
			try{
				Connect(streamStore);
			}catch(e){
				failCall("ä»Žæµä¸­æ‰“å¼€å½•éŸ³å¤±è´¥ï¼š"+e.message);
				return;
			}
			ok();
			return;
		};
		
		
		//***********æ‰“å¼€éº¦å…‹é£Žå¾—åˆ°å…¨å±€çš„éŸ³é¢‘æµ************
		var codeFail=function(code,msg){
			try{//è·¨åŸŸçš„ä¼˜å…ˆæ£€æµ‹ä¸€ä¸‹
				window.top.a;
			}catch(e){
				failCall('æ— æƒå½•éŸ³(è·¨åŸŸï¼Œè¯·å°è¯•ç»™iframeæ·»åŠ éº¦å…‹é£Žè®¿é—®ç­–ç•¥ï¼Œå¦‚allow="camera;microphone")');
				return;
			};
			
			if(/Permission|Allow/i.test(code)){
				failCall("ç”¨æˆ·æ‹’ç»äº†å½•éŸ³æƒé™",true);
			}else if(window.isSecureContext===false){
				failCall("æ— æƒå½•éŸ³(éœ€https)");
			}else if(/Found/i.test(code)){//å¯èƒ½æ˜¯éžå®‰å…¨çŽ¯å¢ƒå¯¼è‡´çš„æ²¡æœ‰è®¾å¤‡
				failCall(msg+"ï¼Œæ— å¯ç”¨éº¦å…‹é£Ž");
			}else{
				failCall(msg);
			};
		};
		
		
		//å¦‚æžœå·²æ‰“å¼€å¹¶ä¸”æœ‰æ•ˆå°±ä¸è¦å†æ‰“å¼€äº†
		if(Recorder.IsOpen()){
			ok();
			return;
		};
		if(!Recorder.Support()){
			codeFail("","æ­¤æµè§ˆå™¨ä¸æ”¯æŒå½•éŸ³");
			return;
		};
				
		//è¯·æ±‚æƒé™ï¼Œå¦‚æžœä»ŽæœªæŽˆæƒï¼Œä¸€èˆ¬æµè§ˆå™¨ä¼šå¼¹å‡ºæƒé™è¯·æ±‚å¼¹æ¡†
		var f1=function(stream){
			Recorder.Stream=stream;
			stream._call={};//æ­¤æ—¶is openï¼Œä½†å¹¶æœªconnectï¼Œæ˜¯å…è®¸ç»‘å®šæŽ¥æ”¶æ•°æ®çš„
			if(lockFail())return;
			
			//https://github.com/xiangyuecn/Recorder/issues/14 èŽ·å–åˆ°çš„track.readyState!="live"ï¼Œåˆšåˆšå›žè°ƒæ—¶å¯èƒ½æ˜¯æ­£å¸¸çš„ï¼Œä½†è¿‡ä¸€ä¸‹å¯èƒ½å°±è¢«å…³æŽ‰äº†ï¼ŒåŽŸå› ä¸æ˜Žã€‚å»¶è¿Ÿä¸€ä¸‹ä¿è¯çœŸå¼‚æ­¥ã€‚å¯¹æ­£å¸¸æµè§ˆå™¨ä¸å½±å“
			setTimeout(function(){
				if(lockFail())return;
				
				if(Recorder.IsOpen()){
					Connect();
					ok();
				}else{
					failCall("å½•éŸ³åŠŸèƒ½æ— æ•ˆï¼šæ— éŸ³é¢‘æµ");
				};
			},100);
		};
		var f2=function(e){
			var code=e.name||e.message||e.code+":"+e;
			CLog("è¯·æ±‚å½•éŸ³æƒé™é”™è¯¯",1,e);
			
			codeFail(code,"æ— æ³•å½•éŸ³ï¼š"+code);
		};
		var pro=Recorder.Scope.getUserMedia({audio:This.set.audioTrackSet||true},f1,f2);
		if(pro&&pro.then){
			pro.then(f1)[True&&"catch"](f2); //fix å…³é”®å­—ï¼Œä¿è¯catchåŽ‹ç¼©æ—¶ä¿æŒå­—ç¬¦ä¸²å½¢å¼
		};
	}
	//å…³é—­é‡Šæ”¾å½•éŸ³èµ„æº
	,close:function(call){
		call=call||NOOP;
		
		var This=this,streamStore=This._streamStore();
		This._stop();
		
		var Lock=streamStore.Sync;
		This._O=0;
		if(This._O_!=Lock.O){
			//å”¯ä¸€èµ„æºStreamçš„æŽ§åˆ¶æƒå·²äº¤ç»™æ–°å¯¹è±¡ï¼Œè¿™é‡Œä¸èƒ½å…³é—­ã€‚æ­¤å¤„åœ¨æ¯æ¬¡éƒ½å¼¹æƒé™çš„æµè§ˆå™¨å†…å¯èƒ½å­˜åœ¨æ³„æ¼ï¼Œæ–°å¯¹è±¡è¢«æ‹’ç»æƒé™å¯èƒ½ä¸ä¼šè°ƒç”¨closeï¼Œå¿½ç•¥è¿™ç§ä¸å¤„ç†
			CLog("closeè¢«å¿½ç•¥",3);
			call();
			return;
		};
		Lock.C++;//èŽ·å¾—æŽ§åˆ¶æƒ
		
		Disconnect(streamStore);
		
		CLog("close");
		call();
	}
	
	
	
	
	
	/*æ¨¡æ‹Ÿä¸€æ®µå½•éŸ³æ•°æ®ï¼ŒåŽé¢å¯ä»¥è°ƒç”¨stopè¿›è¡Œç¼–ç ï¼Œéœ€æä¾›pcmæ•°æ®[1,2,3...]ï¼Œpcmçš„é‡‡æ ·çŽ‡*/
	,mock:function(pcmData,pcmSampleRate){
		var This=this;
		This._stop();//æ¸…ç†æŽ‰å·²æœ‰çš„èµ„æº
		
		This.isMock=1;
		This.mockEnvInfo=null;
		This.buffers=[pcmData];
		This.recSize=pcmData.length;
		This.srcSampleRate=pcmSampleRate;
		return This;
	}
	,envCheck:function(envInfo){//å¹³å°çŽ¯å¢ƒä¸‹çš„å¯ç”¨æ€§æ£€æŸ¥ï¼Œä»»ä½•æ—¶å€™éƒ½å¯ä»¥è°ƒç”¨æ£€æŸ¥ï¼Œè¿”å›žerrMsg:""æ­£å¸¸ï¼Œ"å¤±è´¥åŽŸå› "
		//envInfo={envName:"H5",canProcess:true}
		var errMsg,This=this,set=This.set;
		
		//ç¼–ç å™¨æ£€æŸ¥çŽ¯å¢ƒä¸‹é…ç½®æ˜¯å¦å¯ç”¨
		if(!errMsg){
			if(This[set.type+"_envCheck"]){//ç¼–ç å™¨å·²å®žçŽ°çŽ¯å¢ƒæ£€æŸ¥
				errMsg=This[set.type+"_envCheck"](envInfo,set);
			}else{//æœªå®žçŽ°æ£€æŸ¥çš„æ‰‹åŠ¨æ£€æŸ¥é…ç½®æ˜¯å¦æœ‰æ•ˆ
				if(set.takeoffEncodeChunk){
					errMsg=set.type+"ç±»åž‹ä¸æ”¯æŒè®¾ç½®takeoffEncodeChunk";
				};
			};
		};
		
		return errMsg||"";
	}
	,envStart:function(mockEnvInfo,sampleRate){//å¹³å°çŽ¯å¢ƒç›¸å…³çš„startè°ƒç”¨
		var This=this,set=This.set;
		This.isMock=mockEnvInfo?1:0;//éžH5çŽ¯å¢ƒéœ€è¦å¯ç”¨mockï¼Œå¹¶æä¾›envCheckéœ€è¦çš„çŽ¯å¢ƒä¿¡æ¯
		This.mockEnvInfo=mockEnvInfo;
		This.buffers=[];//æ•°æ®ç¼“å†²
		This.recSize=0;//æ•°æ®å¤§å°
		
		This.envInLast=0;//envInæŽ¥æ”¶åˆ°æœ€åŽå½•éŸ³å†…å®¹çš„æ—¶é—´
		This.envInFirst=0;//envInæŽ¥æ”¶åˆ°çš„é¦–ä¸ªå½•éŸ³å†…å®¹çš„å½•åˆ¶æ—¶é—´
		This.envInFix=0;//è¡¥å¿çš„æ€»æ—¶é—´
		This.envInFixTs=[];//è¡¥å¿è®¡æ•°åˆ—è¡¨
		
		set.sampleRate=Math.min(sampleRate,set.sampleRate);//engineCtxéœ€è¦æå‰ç¡®å®šæœ€ç»ˆçš„é‡‡æ ·çŽ‡
		This.srcSampleRate=sampleRate;
		
		This.engineCtx=0;
		//æ­¤ç±»åž‹æœ‰è¾¹å½•è¾¹è½¬ç (Worker)æ”¯æŒ
		if(This[set.type+"_start"]){
			var engineCtx=This.engineCtx=This[set.type+"_start"](set);
			if(engineCtx){
				engineCtx.pcmDatas=[];
				engineCtx.pcmSize=0;
			};
		};
	}
	,envResume:function(){//å’Œå¹³å°çŽ¯å¢ƒæ— å…³çš„æ¢å¤å½•éŸ³
		//é‡æ–°å¼€å§‹è®¡æ•°
		this.envInFixTs=[];
	}
	,envIn:function(pcm,sum){//å’Œå¹³å°çŽ¯å¢ƒæ— å…³çš„pcm[Int16]è¾“å…¥
		var This=this,set=This.set,engineCtx=This.engineCtx;
		var bufferSampleRate=This.srcSampleRate;
		var size=pcm.length;
		var powerLevel=Recorder.PowerLevel(sum,size);
		
		var buffers=This.buffers;
		var bufferFirstIdx=buffers.length;//ä¹‹å‰çš„bufferéƒ½æ˜¯ç»è¿‡onProcesså¤„ç†å¥½çš„ï¼Œä¸å…è®¸å†ä¿®æ”¹
		buffers.push(pcm);
		
		//æœ‰engineCtxæ—¶ä¼šè¢«è¦†ç›–ï¼Œè¿™é‡Œä¿å­˜ä¸€ä»½
		var buffersThis=buffers;
		var bufferFirstIdxThis=bufferFirstIdx;
		
		//å¡é¡¿ä¸¢å¤±è¡¥å¿ï¼šå› ä¸ºè®¾å¤‡å¾ˆå¡çš„æ—¶å€™å¯¼è‡´H5æŽ¥æ”¶åˆ°çš„æ•°æ®é‡ä¸å¤Ÿé€ æˆæ’­æ”¾æ—¶å€™å˜é€Ÿï¼Œç»“æžœæ¯”å®žé™…çš„æ—¶é•¿è¦çŸ­ï¼Œæ­¤å¤„ä¿è¯äº†ä¸ä¼šå˜çŸ­ï¼Œä½†ä¸èƒ½ä¿®å¤ä¸¢å¤±çš„éŸ³é¢‘æ•°æ®é€ æˆéŸ³è´¨å˜å·®ã€‚å½“å‰ç®—æ³•é‡‡ç”¨è¾“å…¥æ—¶é—´ä¾¦æµ‹ä¸‹ä¸€å¸§æ˜¯å¦éœ€è¦æ·»åŠ è¡¥å¿å¸§ï¼Œéœ€è¦(6æ¬¡è¾“å…¥||è¶…è¿‡1ç§’)ä»¥ä¸Šæ‰ä¼šå¼€å§‹ä¾¦æµ‹ï¼Œå¦‚æžœæ»‘åŠ¨çª—å£å†…ä¸¢å¤±è¶…è¿‡1/3å°±ä¼šè¿›è¡Œè¡¥å¿
		var now=Date.now();
		var pcmTime=Math.round(size/bufferSampleRate*1000);
		This.envInLast=now;
		if(This.buffers.length==1){//è®°ä¸‹é¦–ä¸ªå½•éŸ³æ•°æ®çš„å½•åˆ¶æ—¶é—´
			This.envInFirst=now-pcmTime;
		};
		var envInFixTs=This.envInFixTs;
		envInFixTs.splice(0,0,{t:now,d:pcmTime});
		//ä¿ç•™3ç§’çš„è®¡æ•°æ»‘åŠ¨çª—å£ï¼Œå¦å¤–è¶…è¿‡3ç§’çš„åœé¡¿ä¸è¡¥å¿
		var tsInStart=now,tsPcm=0;
		for(var i=0;i<envInFixTs.length;i++){
			var o=envInFixTs[i];
			if(now-o.t>3000){
				envInFixTs.length=i;
				break;
			};
			tsInStart=o.t;
			tsPcm+=o.d;
		};
		//è¾¾åˆ°éœ€è¦çš„æ•°æ®é‡ï¼Œå¼€å§‹ä¾¦æµ‹æ˜¯å¦éœ€è¦è¡¥å¿
		var tsInPrev=envInFixTs[1];
		var tsIn=now-tsInStart;
		var lost=tsIn-tsPcm;
		if( lost>tsIn/3 && (tsInPrev&&tsIn>1000 || envInFixTs.length>=6) ){
			//ä¸¢å¤±è¿‡å¤šï¼Œå¼€å§‹æ‰§è¡Œè¡¥å¿
			var addTime=now-tsInPrev.t-pcmTime;//è·ç¦»ä¸Šæ¬¡è¾“å…¥ä¸¢å¤±è¿™ä¹ˆå¤šms
			if(addTime>pcmTime/5){//ä¸¢å¤±è¶…è¿‡æœ¬å¸§çš„1/5
				var fixOpen=!set.disableEnvInFix;
				CLog("["+now+"]"+(fixOpen?"":"æœª")+"è¡¥å¿"+addTime+"ms",3);
				This.envInFix+=addTime;
				
				//ç”¨é™é»˜è¿›è¡Œè¡¥å¿
				if(fixOpen){
					var addPcm=new Int16Array(addTime*bufferSampleRate/1000);
					size+=addPcm.length;
					buffers.push(addPcm);
				};
			};
		};
		
		
		var sizeOld=This.recSize,addSize=size;
		var bufferSize=sizeOld+addSize;
		This.recSize=bufferSize;//æ­¤å€¼åœ¨onProcessåŽéœ€è¦ä¿®æ­£ï¼Œå¯èƒ½æ–°æ•°æ®è¢«ä¿®æ”¹
		
		
		//æ­¤ç±»åž‹æœ‰è¾¹å½•è¾¹è½¬ç (Worker)æ”¯æŒï¼Œå¼€å¯å®žæ—¶è½¬ç 
		if(engineCtx){
			//è½¬æ¢æˆsetçš„é‡‡æ ·çŽ‡
			var chunkInfo=Recorder.SampleData(buffers,bufferSampleRate,set.sampleRate,engineCtx.chunkInfo);
			engineCtx.chunkInfo=chunkInfo;
			
			sizeOld=engineCtx.pcmSize;
			addSize=chunkInfo.data.length;
			bufferSize=sizeOld+addSize;
			engineCtx.pcmSize=bufferSize;//æ­¤å€¼åœ¨onProcessåŽéœ€è¦ä¿®æ­£ï¼Œå¯èƒ½æ–°æ•°æ®è¢«ä¿®æ”¹
			
			buffers=engineCtx.pcmDatas;
			bufferFirstIdx=buffers.length;
			buffers.push(chunkInfo.data);
			bufferSampleRate=chunkInfo.sampleRate;
		};
		
		var duration=Math.round(bufferSize/bufferSampleRate*1000);
		var bufferNextIdx=buffers.length;
		var bufferNextIdxThis=buffersThis.length;
		
		//å…è®¸å¼‚æ­¥å¤„ç†bufferæ•°æ®
		var asyncEnd=function(){
			//é‡æ–°è®¡ç®—sizeï¼Œå¼‚æ­¥çš„æ—©å·²å‡åŽ»æ·»åŠ çš„ï¼ŒåŒæ­¥çš„éœ€åŽ»æŽ‰æœ¬æ¬¡æ·»åŠ çš„ç„¶åŽé‡æ–°è®¡ç®—
			var num=asyncBegin?0:-addSize;
			var hasClear=buffers[0]==null;
			for(var i=bufferFirstIdx;i<bufferNextIdx;i++){
				var buffer=buffers[i];
				if(buffer==null){//å·²è¢«ä¸»åŠ¨é‡Šæ”¾å†…å­˜ï¼Œæ¯”å¦‚é•¿æ—¶é—´å®žæ—¶ä¼ è¾“å½•éŸ³æ—¶
					hasClear=1;
				}else{
					num+=buffer.length;
					
					//æŽ¨å…¥åŽå°è¾¹å½•è¾¹è½¬ç 
					if(engineCtx&&buffer.length){
						This[set.type+"_encode"](engineCtx,buffer);
					};
				};
			};
			
			//åŒæ­¥æ¸…ç†This.buffersï¼Œä¸ç®¡buffersåˆ°åº•æ¸…äº†å¤šå°‘ä¸ªï¼ŒbuffersThisæ˜¯ä½¿ç”¨ä¸åˆ°çš„è¿›è¡Œå…¨æ¸…
			if(hasClear && engineCtx){
				var i=bufferFirstIdxThis;
				if(buffersThis[0]){
					i=0;
				};
				for(;i<bufferNextIdxThis;i++){
					buffersThis[i]=null;
				};
			};
			
			//ç»Ÿè®¡ä¿®æ”¹åŽçš„sizeï¼Œå¦‚æžœå¼‚æ­¥å‘ç”Ÿclearè¦åŽŸæ ·åŠ å›žæ¥ï¼ŒåŒæ­¥çš„æ— éœ€æ“ä½œ
			if(hasClear){
				num=asyncBegin?addSize:0;
				
				buffers[0]=null;//å½»åº•è¢«æ¸…ç†
			};
			if(engineCtx){
				engineCtx.pcmSize+=num;
			}else{
				This.recSize+=num;
			};
		};
		//å®žæ—¶å›žè°ƒå¤„ç†æ•°æ®ï¼Œå…è®¸ä¿®æ”¹æˆ–æ›¿æ¢ä¸Šæ¬¡å›žè°ƒä»¥æ¥æ–°å¢žçš„æ•°æ® ï¼Œä½†æ˜¯ä¸å…è®¸ä¿®æ”¹å·²å¤„ç†è¿‡çš„ï¼Œä¸å…è®¸å¢žåˆ ç¬¬ä¸€ç»´æ•°ç»„ ï¼Œå…è®¸å°†ç¬¬äºŒç»´æ•°ç»„ä»»æ„ä¿®æ”¹æ›¿æ¢æˆç©ºæ•°ç»„ä¹Ÿå¯ä»¥
		var asyncBegin=set.onProcess(buffers,powerLevel,duration,bufferSampleRate,bufferFirstIdx,asyncEnd);
		
		if(asyncBegin===true){
			//å¼€å¯äº†å¼‚æ­¥æ¨¡å¼ï¼ŒonProcesså·²æŽ¥ç®¡buffersæ–°æ•°æ®ï¼Œç«‹å³æ¸…ç©ºï¼Œé¿å…å‡ºçŽ°æœªå¤„ç†çš„æ•°æ®
			var hasClear=0;
			for(var i=bufferFirstIdx;i<bufferNextIdx;i++){
				if(buffers[i]==null){//å·²è¢«ä¸»åŠ¨é‡Šæ”¾å†…å­˜ï¼Œæ¯”å¦‚é•¿æ—¶é—´å®žæ—¶ä¼ è¾“å½•éŸ³æ—¶ ï¼Œä½†åˆè¦å¼€å¯å¼‚æ­¥æ¨¡å¼ï¼Œæ­¤ç§æƒ…å†µæ˜¯éžæ³•çš„
					hasClear=1;
				}else{
					buffers[i]=new Int16Array(0);
				};
			};
			
			if(hasClear){
				CLog("æœªè¿›å…¥å¼‚æ­¥å‰ä¸èƒ½æ¸…é™¤buffers",3);
			}else{
				//è¿˜åŽŸsizeï¼Œå¼‚æ­¥ç»“æŸåŽå†ç»Ÿè®¡ä»…ä¿®æ”¹åŽçš„sizeï¼Œå¦‚æžœå‘ç”Ÿclearè¦åŽŸæ ·åŠ å›žæ¥
				if(engineCtx){
					engineCtx.pcmSize-=addSize;
				}else{
					This.recSize-=addSize;
				};
			};
		}else{
			asyncEnd();
		};
	}
	
	
	
	
	//å¼€å§‹å½•éŸ³ï¼Œéœ€å…ˆè°ƒç”¨openï¼›åªè¦openæˆåŠŸæ—¶ï¼Œè°ƒç”¨æ­¤æ–¹æ³•æ˜¯å®‰å…¨çš„ï¼Œå¦‚æžœæœªopenå¼ºè¡Œè°ƒç”¨å¯¼è‡´çš„å†…éƒ¨é”™è¯¯å°†ä¸ä¼šæœ‰ä»»ä½•æç¤ºï¼Œstopæ—¶è‡ªç„¶èƒ½å¾—åˆ°é”™è¯¯
	,start:function(){
		var This=this,ctx=Recorder.Ctx;
		
		var isOpen=1;
		if(This.set.sourceStream){//ç›´æŽ¥æä¾›äº†æµï¼Œä»…åˆ¤æ–­æ˜¯å¦è°ƒç”¨äº†open
			if(!This.Stream){
				isOpen=0;
			}
		}else if(!Recorder.IsOpen()){//ç›‘æµ‹å…¨å±€éº¦å…‹é£Žæ˜¯å¦æ‰“å¼€å¹¶ä¸”æœ‰æ•ˆ
			isOpen=0;
		};
		if(!isOpen){
			CLog("æœªopen",1);
			return;
		};
		CLog("å¼€å§‹å½•éŸ³");
		
		This._stop();
		This.state=0;
		This.envStart(null,ctx.sampleRate);
		
		//æ£€æŸ¥openè¿‡ç¨‹ä¸­stopæ˜¯å¦å·²ç»è°ƒç”¨è¿‡
		if(This._SO&&This._SO+1!=This._S){//ä¸Šé¢è°ƒç”¨è¿‡ä¸€æ¬¡ _stop
			//openæœªå®Œæˆå°±è°ƒç”¨äº†stopï¼Œæ­¤ç§æƒ…å†µç»ˆæ­¢startã€‚ä¹Ÿåº”å°½é‡é¿å…å‡ºçŽ°æ­¤æƒ…å†µ
			CLog("startè¢«ä¸­æ–­",3);
			return;
		};
		This._SO=0;
		
		var end=function(){
			This.state=1;
			This.resume();
		};
		if(ctx.state=="suspended"){
			ctx.resume().then(function(){
				CLog("ctx resume");
				end();
			});
		}else{
			end();
		};
	}
	/*æš‚åœå½•éŸ³*/
	,pause:function(){
		var This=this;
		if(This.state){
			This.state=2;
			CLog("pause");
			delete This._streamStore().Stream._call[This.id];
		};
	}
	/*æ¢å¤å½•éŸ³*/
	,resume:function(){
		var This=this;
		if(This.state){
			This.state=1;
			CLog("resume");
			This.envResume();
			
			This._streamStore().Stream._call[This.id]=function(pcm,sum){
				if(This.state==1){
					This.envIn(pcm,sum);
				};
			};
		};
	}
	
	
	
	
	,_stop:function(keepEngine){
		var This=this,set=This.set;
		if(!This.isMock){
			This._S++;
		};
		if(This.state){
			This.pause();
			This.state=0;
		};
		if(!keepEngine && This[set.type+"_stop"]){
			This[set.type+"_stop"](This.engineCtx);
			This.engineCtx=0;
		};
	}
	/*
	ç»“æŸå½•éŸ³å¹¶è¿”å›žå½•éŸ³æ•°æ®blobå¯¹è±¡
		True(blob,duration) blobï¼šå½•éŸ³æ•°æ®audio/mp3|wavæ ¼å¼
							durationï¼šå½•éŸ³æ—¶é•¿ï¼Œå•ä½æ¯«ç§’
		False(msg)
		autoClose:false å¯é€‰ï¼Œæ˜¯å¦è‡ªåŠ¨è°ƒç”¨closeï¼Œé»˜è®¤ä¸ºfalse
	*/
	,stop:function(True,False,autoClose){
		var This=this,set=This.set,t1;
		CLog("Stop "+(This.envInLast?This.envInLast-This.envInFirst+"ms è¡¥"+This.envInFix+"ms":"-"));
		
		var end=function(){
			This._stop();//å½»åº•å…³æŽ‰engineCtx
			if(autoClose){
				This.close();
			};
		};
		var err=function(msg){
			CLog("ç»“æŸå½•éŸ³å¤±è´¥ï¼š"+msg,1);
			False&&False(msg);
			end();
		};
		var ok=function(blob,duration){
			CLog("ç»“æŸå½•éŸ³ ç¼–ç "+(Date.now()-t1)+"ms éŸ³é¢‘"+duration+"ms/"+blob.size+"b");
			if(set.takeoffEncodeChunk){//æŽ¥ç®¡äº†è¾“å‡ºï¼Œæ­¤æ—¶blobé•¿åº¦ä¸º0
				CLog("å¯ç”¨takeoffEncodeChunkåŽstopè¿”å›žçš„blobé•¿åº¦ä¸º0ä¸æä¾›éŸ³é¢‘æ•°æ®",3);
			}else if(blob.size<Math.max(100,duration/2)){//1ç§’å°äºŽ0.5kï¼Ÿ
				err("ç”Ÿæˆçš„"+set.type+"æ— æ•ˆ");
				return;
			};
			True&&True(blob,duration);
			end();
		};
		if(!This.isMock){
			if(!This.state){
				err("æœªå¼€å§‹å½•éŸ³");
				return;
			};
			This._stop(true);
		};
		var size=This.recSize;
		if(!size){
			err("æœªé‡‡é›†åˆ°å½•éŸ³");
			return;
		};
		if(!This.buffers[0]){
			err("éŸ³é¢‘è¢«é‡Šæ”¾");
			return;
		};
		if(!This[set.type]){
			err("æœªåŠ è½½"+set.type+"ç¼–ç å™¨");
			return;
		};
		
		//çŽ¯å¢ƒé…ç½®æ£€æŸ¥ï¼Œæ­¤å¤„ä»…é’ˆå¯¹mockè°ƒç”¨ï¼Œå› ä¸ºopenå·²ç»æ£€æŸ¥è¿‡äº†
		if(This.isMock){
			var checkMsg=This.envCheck(This.mockEnvInfo||{envName:"mock",canProcess:false});//æ²¡æœ‰æä¾›çŽ¯å¢ƒä¿¡æ¯çš„mockæ—¶æ²¡æœ‰onProcesså›žè°ƒ
			if(checkMsg){
				err("å½•éŸ³é”™è¯¯ï¼š"+checkMsg);
				return;
			};
		};
		
		//æ­¤ç±»åž‹æœ‰è¾¹å½•è¾¹è½¬ç (Worker)æ”¯æŒ
		var engineCtx=This.engineCtx;
		if(This[set.type+"_complete"]&&engineCtx){
			var duration=Math.round(engineCtx.pcmSize/set.sampleRate*1000);//é‡‡ç”¨åŽçš„æ•°æ®é•¿åº¦å’Œbuffersçš„é•¿åº¦å¯èƒ½å¾®å°çš„ä¸ä¸€è‡´ï¼Œæ˜¯é‡‡æ ·çŽ‡è¿žç»­è½¬æ¢çš„ç²¾åº¦é—®é¢˜
			
			t1=Date.now();
			This[set.type+"_complete"](engineCtx,function(blob){
				ok(blob,duration);
			},err);
			return;
		};
		
		//æ ‡å‡†UIçº¿ç¨‹è½¬ç ï¼Œè°ƒæ•´é‡‡æ ·çŽ‡
		t1=Date.now();
		var chunk=Recorder.SampleData(This.buffers,This.srcSampleRate,set.sampleRate);
		
		set.sampleRate=chunk.sampleRate;
		var res=chunk.data;
		var duration=Math.round(res.length/set.sampleRate*1000);
		
		CLog("é‡‡æ ·"+size+"->"+res.length+" èŠ±:"+(Date.now()-t1)+"ms");
		
		setTimeout(function(){
			t1=Date.now();
			This[set.type](res,function(blob){
				ok(blob,duration);
			},function(msg){
				err(msg);
			});
		});
	}

};

if(window.Recorder){
	window.Recorder.Destroy();
};
window.Recorder=Recorder;

//end ****copyæºç ç»“æŸ*****
Recorder.LM=LM;

//æµé‡ç»Ÿè®¡ç”¨1åƒç´ å›¾ç‰‡åœ°å€ï¼Œè®¾ç½®ä¸ºç©ºå°†ä¸å‚ä¸Žç»Ÿè®¡
Recorder.TrafficImgUrl="";
Recorder.Traffic=function(){
	var imgUrl=Recorder.TrafficImgUrl;
	if(imgUrl){
		var data=Recorder.Traffic;
		var idf=location.href.replace(/#.*/,"");
		
		if(imgUrl.indexOf("//")==0){
			//ç»™urlåŠ ä¸Šhttpå‰ç¼€ï¼Œå¦‚æžœæ˜¯fileåè®®ä¸‹ï¼Œä¸åŠ å‰ç¼€æ²¡æ³•ç”¨
			if(/^https:/i.test(idf)){
				imgUrl="https:"+imgUrl;
			}else{
				imgUrl="http:"+imgUrl;
			};
		};
		
		if(!data[idf]){
			data[idf]=1;
			
			var img=new Image();
			img.src=imgUrl;
			CLog("Traffic Analysis Image: Recorder.TrafficImgUrl="+Recorder.TrafficImgUrl);
		};
	};
};

}));